package cn.hunqing.web.service.impl;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.hunqing.web.dto.InvitationForm;
import cn.hunqing.web.dto.MyCardSimpleDto;
import cn.hunqing.web.dto.TemplateSimpleDto;
import cn.hunqing.web.dto.WeddingInvitationCommentDto;
import cn.hunqing.web.dto.WeddingInvitationDto;
import cn.hunqing.web.entity.MyCard;
import cn.hunqing.web.entity.Template;
import cn.hunqing.web.entity.WeddingInvitation;
import cn.hunqing.web.entity.WeddingInvitationComment;
import cn.hunqing.web.mapper.TemplateMapper;
import cn.hunqing.web.mapper.WeddingInvitationCommentMapper;
import cn.hunqing.web.mapper.WeddingInvitationMapper;
import cn.hunqing.web.msg.MakeInvitationMsgs;
import cn.hunqing.web.service.PayCodeService;
import cn.hunqing.web.service.WeChatService;
import cn.hunqing.web.service.WeddingInvitationService;
import freemarker.template.Configuration;
import freemarker.template.TemplateException;

@Service
public class WeddingInvitationServiceImpl implements WeddingInvitationService {

	private Configuration cfg = new Configuration(Configuration.VERSION_2_3_23);
	
	@Autowired
	private WeddingInvitationMapper weddingInvitationMapper;
	@Autowired
	private TemplateMapper templateMapper;
	@Autowired
	private WeddingInvitationCommentMapper weddingInvitationCommentMapper;
	
	@Autowired
	private WeChatService weChatService;
	@Autowired
	private PayCodeService payCodeService;

	@Override
	public WeddingInvitationDto getWeddingInvitationDto(int weddingInvitationId) {
		WeddingInvitation weddingInvitation = weddingInvitationMapper.get(weddingInvitationId);
		return WeddingInvitationDto.buildFrom(weddingInvitation);
	}

	@Override
	public MyCardSimpleDto getWeddingInvitationPreviewDto(int weddingInvitationIdInt) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<MyCardSimpleDto> getMyCards(int userId) {
		List<MyCard> myCards = weddingInvitationMapper.getMyCards(userId);
		if(myCards != null){
			List<MyCardSimpleDto> result = new ArrayList<>();
			myCards.forEach(myCard -> {
				MyCardSimpleDto myCardSimpleDto = MyCardSimpleDto.buildFrom(myCard);
//				myCardSimpleDto.setPreview(generateTemplatePreview(myCardSimpleDto));
//				weChatService.getShareConfig("http://www.100hunqing.cn/hunqing/cards/"+myCardSimpleDto.getWeddingInvitationId());
//				weChatService.getShareConfig("http://www.100hunqing.cn/hunqing/cards");
				result.add(myCardSimpleDto);
			});
			return result;
		}
		return null;
	}
	
	@SuppressWarnings("unused")
	private String generateTemplatePreview(MyCardSimpleDto myCardSimpleDto) {
		try {
			freemarker.template.Template t = new freemarker.template.Template("invitation teomplate",
					new StringReader(myCardSimpleDto.getPreview()), cfg);
			Map<String, Object> root = new HashMap<>();
			root.put("bridegroom", myCardSimpleDto.getBridegroom());
			root.put("bride", myCardSimpleDto.getBride());
			root.put("weddingDay", myCardSimpleDto.getWeddingDay());
			root.put("weddingHotel", myCardSimpleDto.getWeddingHotel());
			root.put("weddingAddress", myCardSimpleDto.getWeddingAddress());
			root.put("weddingHall", myCardSimpleDto.getWeddingHall());
			StringWriter sw = new StringWriter();
			t.process(root, sw);
			sw.flush();
			return sw.toString();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TemplateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public InvitationForm getInvitationFormData(int weddingInvitationId, int userId) {
		WeddingInvitation weddingInvitation = weddingInvitationMapper.getByInvitationIdAndUserId(weddingInvitationId,userId);
		if(weddingInvitation ==null){
			throw new RuntimeException(MakeInvitationMsgs.NOT_FOUND_CARD);
		}
		Template template = templateMapper.get(weddingInvitation.getTemplateId());
		return InvitationForm.buildFrom(weddingInvitation,template);
	}

	@Override
	public int create(InvitationForm invitationForm,int userId,int createdBy) {
		Template template = templateMapper.get(invitationForm.getTemplateId());
		if(template ==null){
			throw new RuntimeException(MakeInvitationMsgs.NOT_FOUND_TEMPLATE);
		}
		
		WeddingInvitation weddingInvitation = InvitationForm.extract(invitationForm);
		weddingInvitation.setUserId(userId);
		weddingInvitation.setCreatedBy(userId);
		weddingInvitation.setCreatedAt(new Date());
		weddingInvitationMapper.insert(weddingInvitation);
		
		return weddingInvitation.getId();
	}

	@Override
	public int update(InvitationForm invitationForm,int updatedBy) {
		WeddingInvitation weddingInvitation = weddingInvitationMapper.get(invitationForm.getWeddingInvitationId());
		if(weddingInvitation ==null){
			throw new RuntimeException(MakeInvitationMsgs.NOT_FOUND_CARD);
		}
		weddingInvitation.setAddress(invitationForm.getAddress());
		weddingInvitation.setBackgroundMusic(invitationForm.getBackgroundMusic());
		weddingInvitation.setBride(invitationForm.getBride());
		weddingInvitation.setBridegroom(invitationForm.getBridegroom());
		weddingInvitation.setHotel(invitationForm.getHotel());
		weddingInvitation.setLoveStoryContent(invitationForm.getLoveStoryContent());
		weddingInvitation.setLoveStoryPicture(invitationForm.getLoveStoryPicture());
		weddingInvitation.setLoveStoryVideo(invitationForm.getLoveStoryVideo());
		weddingInvitation.setWeddingDay_D(invitationForm.getWeddingDay_D());
		weddingInvitation.setWeddingDay_M(invitationForm.getWeddingDay_M());
		weddingInvitation.setWeddingDay_Y(invitationForm.getWeddingDay_Y());
		weddingInvitation.setStartTime_HR(invitationForm.getStartTime_HR());
		weddingInvitation.setStartTime_MIN(invitationForm.getStartTime_MIN());
		weddingInvitation.setWeddingPhotos(invitationForm.getWeddingPhotos());
		weddingInvitation.setUpdatedAt(new Date());
		weddingInvitation.setUpdatedBy(updatedBy);
		weddingInvitationMapper.update(weddingInvitation);
		return weddingInvitation.getId();
	}

	@Override
	public void createNewComment(int weddingInvitationIdInt, String commentName, String commentValue) {
		WeddingInvitationComment newWeddingInvitationComment = new WeddingInvitationComment();
		newWeddingInvitationComment.setComment(commentValue);
		newWeddingInvitationComment.setUserName(commentName);
		newWeddingInvitationComment.setWeddingInvitationId(weddingInvitationIdInt);
		newWeddingInvitationComment.setCreatedAt(new Date());
		weddingInvitationCommentMapper.insert(newWeddingInvitationComment);
	}

	@Override
	public List<WeddingInvitationCommentDto> getInvitationComments(int weddingInvitationIdInt) {
		List<WeddingInvitationCommentDto> result = new ArrayList<>();
		List<WeddingInvitationComment> weddingInvitationComments = weddingInvitationCommentMapper.find(weddingInvitationIdInt);
		if(weddingInvitationComments != null && !weddingInvitationComments.isEmpty()){
			weddingInvitationComments.forEach(weddingInvitationComment -> {
				result.add(WeddingInvitationCommentDto.buildFrom(weddingInvitationComment));});
		}
		return result;
	}

	@Override
	public TemplateSimpleDto getTemplateByInvitationId(int weddingInvitationId) {
		WeddingInvitation weddingInvitation = weddingInvitationMapper.get(weddingInvitationId);
		Template template = templateMapper.get(weddingInvitation.getTemplateId());
		if(template != null){
			TemplateSimpleDto templateSimpleDto = TemplateSimpleDto.buildFrom(template);
//			templateSimpleDto.setPreview(generateTemplatePreview(templateSimpleDto.getPreview(),null));
			return templateSimpleDto;
		}
		return null;
	}

	@Override
	public int deleteMyCardById(int invitationId) {
		
		return weddingInvitationMapper.delete(invitationId);
	}

	@Override
	public void payByCode(int weddingInvitationIdInt, String payCode, int userId) {
		payCodeService.toUsePayCode(payCode, userId);
		weddingInvitationMapper.updatePayStatus(weddingInvitationIdInt, 1);
	}

}
